/******************************************************************************
 * @File name   :      ActivationServiceImpl.java
 *
 * @Author      :      ANMA
 *
 * @Date        :      Jul 31, 2015
 *
 * @Copyright Notice: 
 * Copyright (c) 2014 DMS, Inc. All  Rights Reserved.
 * This software is published under the terms of the DMS Software
 * License version 1.0, a copy of which has been included with this
 * distribution in the LICENSE.txt file.
 * 
 * ----------------------------------------------------------------------------
 * Date                         Who         Version         Comments
 * Jul 31, 2015 2:41:00 PM    ANMA      1.0            Initial Version
 *****************************************************************************/
package com.cap.bts.crmdp.dealer.activation.service.impl;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cap.bts.commonfunc.common.constant.SmsTemplateNoConstants;
import com.cap.bts.commonfunc.common.constant.SmsTemplateVariable;
import com.cap.bts.commonfunc.common.dto.SmsContentDetailDto;
import com.cap.bts.commonfunc.common.util.UserUtil;
import com.cap.bts.crmdp.dealer.activation.dao.IPackageRedemptionLinesDao;
import com.cap.bts.crmdp.dealer.activation.dao.IPackageRedemptionLinesItemDao;
import com.cap.bts.crmdp.dealer.activation.domain.PackageRedemptionLines;
import com.cap.bts.crmdp.dealer.activation.dto.ActivationQueryDto;
import com.cap.bts.crmdp.dealer.activation.dto.ActivationResultsDto;
import com.cap.bts.crmdp.dealer.activation.service.IActivationService;
import com.cap.bts.crmdp.dealer.coupon.constants.CouponConstants;
import com.cap.bts.crmdp.dealer.coupon.dao.ITicketLineDefineDao;
import com.cap.bts.crmdp.dealer.member.dao.IMaintainCarPlateDao;
import com.cap.bts.crmdp.dealer.member.dao.IMaintainMemberDao;
import com.cap.bts.crmdp.dealer.member.domain.CarPlateInfo;
import com.cap.bts.crmdp.dealer.member.domain.MemberInfo;
import com.cap.bts.crmdp.dealer.member.service.IMaintainCarPlateService;
import com.cap.bts.crmdp.dealer.packagegift.service.IMemberGiftService;
import com.cap.bts.crmdp.dealer.purchase.dao.IMemberPackageDao;
import com.cap.bts.crmdp.dealer.purchase.dao.IPackageDefinitionDao;
import com.cap.bts.crmdp.dealer.purchase.domain.MemberPackageInfo;
import com.cap.bts.crmdp.dealer.purchase.domain.PackageDefinition;
import com.cap.bts.crmdp.dealer.purchase.dto.MemberPackageInfoSubmitDto;
import com.cap.bts.crmdp.dealer.purchase.service.IPurchasePackageService;
import com.cap.bts.crmdp.dealer.redemption.dao.IPackageRedemptionDao;
import com.cap.bts.crmdp.dealer.redemption.domain.MemberPackageRedemption;
import com.cap.bts.framework.common.exception.AppException;
import com.cap.bts.framework.common.util.Utils;
import com.cap.bts.framework.sms.service.ISmContentService;

/**
 * 
 */
@Transactional(rollbackFor = AppException.class)
@Service
public class ActivationServiceImpl implements IActivationService {

    private static final Logger LOGGER = Logger.getLogger(ActivationServiceImpl.class);

    private static final String ERR_MSG_NO_CARPLATE = "该会员没有绑定的车牌.";

    @Resource(name = "memberPackageDao")
    private IMemberPackageDao memberPackageDao;

    @Resource(name = "packageDefinitionDao")
    private IPackageDefinitionDao packageDefinitionDao;

    @Resource(name = "packageRedemptionLinesDao")
    IPackageRedemptionLinesDao packageRedemptionLinesDao;

    @Resource(name = "packageRedemptionDao")
    private IPackageRedemptionDao memberPackageRedemptionDao;

    @Autowired
    IMaintainCarPlateService maintainCarPlateService;

    @Resource(name = "maintainCarPlateDao")
    private IMaintainCarPlateDao maintainCarPlateDao;

    @Autowired
    IPurchasePackageService purchasePackageService;

    @Autowired
    IMemberGiftService memberGiftService;

    @Autowired
    IMaintainMemberDao memberDao;

    @Autowired
    ISmContentService smContentService;

    @Autowired
    ITicketLineDefineDao iTicketLineDefineDao;

    @Autowired
    IPackageRedemptionLinesItemDao packageRedemptionLinesItemDao;

    /*
     * (non-Javadoc)
     * 
     * @see com.cap.bts.crmdp.dealer.activation.service.IActivationService#
     * saveMemberActivation
     * (com.cap.bts.crmdp.dealer.activation.dto.ActivationQueryDto)
     */
    @Override
    public ActivationResultsDto saveMemberPurchaseAndActivationNow(MemberPackageInfoSubmitDto dto)
        throws AppException {
        //
        // 先购买再激活
        //
        ActivationQueryDto activationQueryDto = new ActivationQueryDto();
        if (dto.getPackageDefId() != null) {
            //
            // 购买
            //
            activationQueryDto.setPackageDefId(dto.getPackageDefId());
            dto.setIsPhysicalCard((byte) 1);
            purchasePackageService.purchasePackage(dto);
        }

        activationQueryDto.setActiveMemberId(dto.getMemberId());
        activationQueryDto.setMobilePhone(dto.getMobilePhone());
        activationQueryDto.setMemberName(dto.getMemberName());
        activationQueryDto.setCarPlate(dto.getCarPlate());
        activationQueryDto.setPackageNumber(dto.getPackageNumber());
        activationQueryDto.setPackageActiveCode(dto.getPackageActiveCode());
        activationQueryDto.setPrice(dto.getPrice());
        //
        // 激活
        //
        return this.saveMemberActivation(activationQueryDto);

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.cap.bts.crmdp.dealer.activation.service.IActivationService#
     * saveMemberActivation
     * (com.cap.bts.crmdp.dealer.activation.dto.ActivationQueryDto)
     */
    @Override
    public ActivationResultsDto saveMemberActivation(ActivationQueryDto dto) throws AppException {

        ActivationResultsDto activationResultsDto = new ActivationResultsDto();
        Long activeMemberId = dto.getActiveMemberId();
        String carPlate = dto.getCarPlate();
        String errorMsg = "";
        // 依据车牌和会员ID找到车辆信息。
        List<CarPlateInfo> carPlateList = maintainCarPlateService
            .getCarPlateInfoListByCarPlateOrMemberId(carPlate, activeMemberId);
        if (carPlateList == null || carPlateList.isEmpty()) {
            throw new AppException("ERROR", ERR_MSG_NO_CARPLATE);
        }
        
        MemberPackageInfo cmpi = memberPackageDao.checkPackageNumberByActivationDto(dto);
        if (cmpi == null) {
            throw new AppException("ERROR", "卡号有误，请重新输入。");
        }
        MemberPackageInfo memberPackageInfo = memberPackageDao
            .getMemberPackageInfoByActivationDto(dto);
        if (memberPackageInfo != null) {
//            Long packageId = memberPackageInfo.getId()

            // 如果是当场激活时候，直接从画面内容中取得PackageDefId
            Long pkgDefId = dto.getPackageDefId();
            // 如果是事后激活，则从数据库中取得PackageDefId(PackageDefId在仅购买操作时保存提交到数据库)
            PackageDefinition pd = packageDefinitionDao.findById(memberPackageInfo
                .getPackageDefinition().getId());
            int validPeriod = pd.getValidPeriod();
            String unitOfPeriod = pd.getUnitOfPeriod();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());

            dto.setPackageDefId(pkgDefId);
            // 车牌ID
            Long carId = carPlateList.get(0).getId();
            Long maxPurchaseNum = packageDefinitionDao
                .findById(cmpi.getPackageDefinition().getId()).getNumberSequence();
            int purchaseNum = 0;
            // 对应的套餐定义，存在相同CODE组,但组中最大购买次数相同,则当前购买次数按组计算
            purchaseNum = memberPackageDao.getPackagesPurchaseNumWithSamePackageCode(UserUtil.getCurrentUser()
                    .getDealerId(), dto.getActiveMemberId(), carId, pd.getCode());

            if (dto.getPackageDefId() == null) {
                dto.setPackageDefId(cmpi.getPackageDefinition().getId());
            }
            
            // 超过
            if (maxPurchaseNum != 0 && maxPurchaseNum < purchaseNum+1  && !dto.isGiftPurchase()) {
                // 如果是礼品套餐则最大购买次数失效,最大购买次数为0时
                errorMsg = "套餐:"
                    + packageDefinitionDao.findById(cmpi.getPackageDefinition().getId()).getName()
                    + ",已超过最大购买使用次数:" + maxPurchaseNum + ",不能激活！";
                throw new AppException("ERROR", errorMsg);
            }

            MemberPackageInfoSubmitDto memberPackageInfoSubmitDto = new MemberPackageInfoSubmitDto();
            memberPackageInfoSubmitDto.setCarPlate(carPlate);
            memberPackageInfoSubmitDto.setMemberId(activeMemberId);
            memberPackageInfoSubmitDto.setDealerId(memberPackageInfo.getDealerId());
            memberPackageInfoSubmitDto.setPackageDefId(dto.getPackageDefId());
            memberPackageInfoSubmitDto.setPackageNumber(memberPackageInfo.getPackageNumber());
            memberPackageInfoSubmitDto.setPackageId(memberPackageInfo.getId());
            MemberPackageInfoSubmitDto memberPackageInfoSubmitDto1 = new MemberPackageInfoSubmitDto();
            memberPackageInfoSubmitDto1.setCarPlate(carPlate);
            memberPackageInfoSubmitDto1.setMemberId(activeMemberId);
            memberPackageInfoSubmitDto1.setDealerId(memberPackageInfo.getDealerId());
            memberPackageInfoSubmitDto1.setPackageDefId(dto.getPackageDefId());
            memberPackageInfoSubmitDto1.setPackageNumber(memberPackageInfo.getPackageNumber());
            if (!dto.isGiftPurchase()) {
                memberGiftService.processTicketGift(memberPackageInfoSubmitDto);
                memberGiftService.processPackageGift(memberPackageInfoSubmitDto1);
            } else {
                // 设置卡片为礼物标致，为使用页面显示时提示（赠送）使用
                memberPackageInfo.setIsGift(1);
            }
            // 更新PackageDefId
            PackageDefinition pd1 = packageDefinitionDao.findById(dto.getPackageDefId());
            memberPackageInfo.setPackageDefinition(pd1);
            // 更新 此卡 的 状态、激活是门店id、激活人id和 激活车牌id

            // 已生成0 已售出1 已激活2 已使用3 已用完4 已退款5
            memberPackageInfo.setStatus((byte) 2);

            // 激活是门店id
            memberPackageInfo.setDealerId(memberPackageInfo.getDealerId());
            
            if(memberPackageInfo.getDealerId()!=UserUtil.getCurrentUser().getDealerId()){
                throw new AppException("saveMemberActivation", "该卡非本店销售,请到相应的购买门店："+memberPackageInfo.getDealerId()+",去激活!");
            }
            
            // 激活人id
            memberPackageInfo.setMemberId(activeMemberId);

            // 激活车牌id
            memberPackageInfo.setActiveCarId(carId);
            memberPackageInfo.setActiveMemberId(activeMemberId);
            memberPackageInfo.setActiveDealerId(UserUtil.getCurrentUser().getDealerId());
            // 激活日期
            memberPackageInfo.setActiveDate(calendar.getTime());
            // 价格
            if(dto.getPrice()!=null){
                memberPackageInfo.setActualPrice(dto.getPrice());
            }
            // 失效日期
            if ("Y".equalsIgnoreCase(unitOfPeriod)) {
                calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + validPeriod);
            }
            if ("M".equalsIgnoreCase(unitOfPeriod)) {
                calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + validPeriod);
            }
            if ("D".equalsIgnoreCase(unitOfPeriod)) {
                calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + validPeriod);
            }
            memberPackageInfo.setExpireDate(calendar.getTime());

            //
            // memberPackageInfo.set

            // 更新表 会员-卡
            memberPackageDao.update(memberPackageInfo);

            //
            // 更新 会员-车牌 关系表， 设置会员状态为已激活。
            //
            CarPlateInfo cinfo = maintainCarPlateDao.findById(carId);
            if (cinfo != null) {
                cinfo.setMemberStatus("1");
                maintainCarPlateDao.update(cinfo);
            } else {
                errorMsg = "输入车牌有误，请检查。";
            }
            if (Utils.isNullOrEmpty(errorMsg) && !dto.isGiftPurchase()) {
                // send SMS Message
                Map<String, String> paraMap = new HashMap<String, String>();
                MemberInfo memberInfo = memberDao.findById(activeMemberId);
                SmsContentDetailDto smsDto = new SmsContentDetailDto();
                if (memberInfo != null) {
                    paraMap.put(SmsTemplateVariable.VARIABLE_MEMBER_NAME,
                        memberInfo.getMemberName());
                    paraMap.put(SmsTemplateVariable.VARIABLE_PACKAGE_NAME, memberPackageInfo
                        .getPackageDefinition().getName());
                    paraMap.put(SmsTemplateVariable.VARIABLE_PACKAGE_NUM,
                        memberPackageInfo.getPackageNumber());
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    paraMap.put(SmsTemplateVariable.VARIABLE_EXPIRE_DATE,
                        sdf.format(memberPackageInfo.getExpireDate()));
                    smsDto.setParaMap(paraMap);
                    smsDto.setDestMobile(Long.valueOf(memberInfo.getMobilePhone()));
                    smsDto
                        .setTemplateNo(SmsTemplateNoConstants.PACKAGE_ACTIVE_NOTIFICATION_TEMPLATE_NO);
                    smContentService.createSmsContent(smsDto);
                }
            }
        } else {
            if (memberPackageDao.checkPackageNumberAndActivationCodeByActivationDto(dto) == null) {
                errorMsg = "验证码有误，请重新输入。";
            } else {
                errorMsg = "该卡已被激活，请重新输入。";
            }
        }

        if (Utils.notEmpty(errorMsg)) {
            LOGGER.error(errorMsg);
            throw new AppException("ERROR", errorMsg);
        }
        return activationResultsDto;
    }

    /**
     * {@inheritDoc} overridden: 赠送的优惠券提货券购买时专用方法
     * 
     * @Date : Sep 27, 2015
     * @see com.cap.bts.crmdp.dealer.activation.service.IActivationService#addPackageRedemptionListInfo(java.util.List)
     **/
    @Override
    public void addPackageRedemptionListInfo(
        List<PackageRedemptionLines> packageRedemptionLinesList, Long packageId)
        throws AppException {
        if (packageRedemptionLinesList != null && !packageRedemptionLinesList.isEmpty()) {
            for (int i = 0; i < packageRedemptionLinesList.size(); i++) {
                // 集成套餐定义时新追加
                // 用ticket定义表来更新RedemptionLine表写入description,hasVerificationCode三个字段
                // description
                PackageRedemptionLines saveLine = packageRedemptionLinesDao
                    .findById(packageRedemptionLinesList.get(i).getId());
                String description = iTicketLineDefineDao
                    .getTicketDescriptionInfoByTicketId(packageRedemptionLinesList.get(i)
                        .getTicket().getId());
                if (description != null) {
                    saveLine.setDescription(description);
                }
                // hasVerificationCode
                if (packageRedemptionLinesList.get(i).getTicket().getVerificationMethod()
                    .equals(CouponConstants.NEED_ACTIVICATION_YES)) {
                    saveLine.setHasVerificationCode("Y");
                } else {
                    saveLine.setHasVerificationCode("N");
                }
                // shortName
                String shortName = packageRedemptionLinesList.get(i).getTicket().getTicketName();
                saveLine.setShortName(shortName);
                // 保存状态
                packageRedemptionLinesDao.update(saveLine);

                // 逐行添加package明细到MemberPackageRedemption(会员-卡-使用 表)
                PackageRedemptionLines lines = packageRedemptionLinesList.get(i);
                for (int j = 0; j < lines.getNumberOfUse(); j++) {
                    MemberPackageRedemption memberPackageRedemption = new MemberPackageRedemption();
                    memberPackageRedemption.setPackageId(packageId);
                    memberPackageRedemption.setPackageRedemptionLine(lines);
                    memberPackageRedemption.setShortName(shortName + "(赠送)");
                    // memberPackageRedemption.setShortName(lines.getShortName())
                    if (description != null) {
                        memberPackageRedemption.setDescription(description);
                    }
                    // 验证码
                    memberPackageRedemption.setActivicationCode(String.valueOf((int) (100000 + Math
                        .random() * 1000000)));
                    // 0未使用，1已使用
                    memberPackageRedemption.setStatus(0);

                    memberPackageRedemptionDao.save(memberPackageRedemption);
                }
            }
        }

    }


    /**
     * {@inheritDoc} overridden:
     * 
     * @Date : Oct 9, 2015
     * @see com.cap.bts.crmdp.dealer.activation.service.IActivationService#checkPackageNumberByActivationDto(com.cap.bts.crmdp.dealer.activation.dto.ActivationQueryDto)
     **/
    @Override
    public MemberPackageInfo checkPackageNumberByActivationDto(ActivationQueryDto activationQueryDto)
        throws AppException {
        return memberPackageDao.checkPackageNumberByActivationDto(activationQueryDto);
    }

   
}
